package com.guchenbo.example.dubbo.rpc.proxy;

import com.guchenbo.example.dubbo.rpc.manual.ProviderInvoker;
import com.guchenbo.example.dubbo.rpc.manual.WorkerInvoker;
import java.lang.reflect.Proxy;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcInvocation;

public class JdkProxyFactory {

  public static <T> Invoker<T> getInvoker(Class<T> type, URL url, Object proxy) {
    Invoker<T> worker = new WorkerInvoker<>(type, url, proxy);
    return new ProviderInvoker<>(type, url, worker);
  }

  public static <T> T getProxy(Invoker<T> invoker) {
    return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
        new Class[]{invoker.getInterface()},
        (p, m, a) -> {
          if (m.equals("toString")) {
            return p.toString();
          }
          if (m.equals("equals")) {
            return p.equals(a[0]);
          }
          if (m.equals("hashCode")) {
            return p.hashCode();
          }
          Invocation invocation = new RpcInvocation(m, invoker.getUrl().getServiceInterface(), a);
          return invoker.invoke(invocation).recreate();
        });
  }

}
